package com.goldsprite.gdxcore.physics;

import com.goldsprite.utils.math.Rectangle;
import com.goldsprite.utils.math.Vector2;

public class RectCollider {
	public Vector2 velocity = new Vector2();
	public Rectangle bound = new Rectangle();
	public CollInfo collInfo = new CollInfo();


	public RectCollider() {
	}

	/*
	 矩形间碰撞检测：
	 ．根据当前位置与速度产生的下一位置，计算中途是否会与other产生碰撞，
	 ．．碰撞则设置isCollision为真，碰撞方向为碰撞面方向
	 思路:
	 ．矩形直线运动与矩形碰撞，第一碰撞点会存在两个面，即x速度和y速度垂向面，
	 ．将速度分解为x与y轴分量，
	 ．．假设第一碰撞点为x轴垂向面，则可知此时两矩形x相等，
	 ．．．根据速度代入x求y，将假想速度1代入原矩形位置想加，
	 ．．．得到假想矩形预计位置1，此时两矩形进行aabb检测，
	 ．．．．如果碰撞则此位置为真实第一碰撞点，
	 ．．．．将原速度x分量设为此速度y不变，就可得到经过阻拦后矩形预计位置
	 ．．．如果x未碰撞，则再次假设碰撞点为y轴垂向面，同理
	 ．．．．如果aabb碰撞则修正速度并设置碰撞为真
	 ．．．．如果未碰撞则整体无碰撞
	 */
	static Rectangle tmpRec = new Rectangle();
	static Vector2 velBack = new Vector2();
	static CollInfo tmpCollInfo = new CollInfo();
	static Vector2 tmpVec = new Vector2();

	public CollInfo overlap(RectCollider other) {
		CollInfo collInfo = tmpCollInfo.reset();
		collInfo.newVelocity.set(velocity);

		//速度为0则无碰撞
		if (velocity.isZero()) {
			return collInfo;
		}

		boolean prevAABB = false;
		boolean oppsite = false;
		float k = velocity.y / velocity.x;
		System.out.println("k: " + k);
		Rectangle laterRec = tmpRec.set(bound.center.x + velocity.x, bound.center.y + velocity.y, bound.halfSize.x, bound.halfSize.y);
		System.out.printf(
			"recInfo: \nafter: {↑%.1f, ↓%.1f, ←%.1f, →%.1f}\nother: {↑%.1f, ↓%.1f, ←%.1f, →%.1f}\n",
			bound.topY(), bound.bottomY(), bound.leftX(), bound.rightX(),
			other.bound.topY(), other.bound.bottomY(), other.bound.leftX(), other.bound.rightX()
		);
		//如果velY不为0则贴到顶部或底部进行判断
		if (velocity.y != 0) {
			float upTrip = other.bound.bottomY() - bound.topY();
			float downTrip = other.bound.topY() - bound.bottomY();

			boolean canArrive = velocity.y > 0 ? velocity.y > upTrip : velocity.y < downTrip;
			if (canArrive) {

				float depY = velocity.y > 0
					? other.bound.bottomY() - laterRec.topY()
					: other.bound.topY() - laterRec.bottomY();
				float mappingX = depY / k;
				velBack.set(mappingX, depY);
				System.out.println("贴到水平边-yVelBack: " + velBack);

				oppsite = Math.signum(velocity.y) != Math.signum(velBack.y);//排除距离不够
				if (oppsite) {
					tmpRec.center.set(laterRec.center.x + velBack.x, laterRec.center.y + velBack.y);
					Rectangle yLaterRec = tmpRec;
					prevAABB = yLaterRec.intersects(other.bound);
					if (prevAABB) {
						collInfo.direction.set(velocity.y > 0 ? Vector2.up : Vector2.down);
						collInfo.newVelocity.set(velBack).scl(0, 1).add(velocity);
					}
				} else System.out.println("oppsite: " + oppsite + ", 距离不够");
			}
		}

		if (!prevAABB && velocity.x != 0) {
			float prevXDistance = velocity.x > 0
				? Math.abs(other.bound.leftX() - bound.rightX())
				: Math.abs(other.bound.rightX() - bound.leftX());
			System.out.println("prevXDistance: " + prevXDistance);
			if (Math.abs(velocity.x) >= prevXDistance) {

				float depX = velocity.x > 0
					? other.bound.leftX() - laterRec.rightX()
					: other.bound.rightX() - laterRec.leftX();
				float mappingY = depX * k;
				velBack.set(depX, mappingY);
				System.out.println(other.bound.leftX() + ", " + laterRec.rightX());
				System.out.println("贴到垂直边-xVelBack: " + velBack);

				oppsite = Math.signum(velocity.x) != Math.signum(velBack.x);//排除距离不够
				if (oppsite) {
					tmpRec.center.set(laterRec.center.x + velBack.x, laterRec.center.y + velBack.y);
					Rectangle xLaterRec = tmpRec;
					prevAABB = xLaterRec.intersects(other.bound);
					if (prevAABB) {
						collInfo.direction.set(velocity.x > 0 ? Vector2.right : Vector2.left);
						collInfo.newVelocity.set(velBack).scl(1, 0).add(velocity);
					}
				} else System.out.println("oppsite: " + oppsite + ", 距离不够");
			}
		}

		collInfo.isCollision = prevAABB;
		if (prevAABB) {
			//计算碰撞矩形开始前距离，用于判断更临近碰撞点: 简单使用中心点计算
			collInfo.distance = tmpVec.set(other.bound.center).sub(bound.center).magnitude();
		}
		return collInfo;
	}

}
